package com.tj.pystandard.tjapi.common.config;


import com.tj.pystandard.tjapi.common.util.RedisUtil;
import com.tj.pystandard.tjapi.common.vo.PageResDTO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;

/**
 * redis缓存-AOP
 *
 * @author qiuting
 * @date 2020/11/18 16:06
 */
@Component
@Aspect
@Slf4j
public class RedisCacheAop {
    @Resource
    private RedisTemplate redisTemplate;

    @Pointcut("@annotation(RedisCacheAspect)")
    public void serviceCache() {
    }

    @Around("serviceCache()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取拦截的方法
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        // 获取注解信息
        RedisCacheAspect aspect = methodSignature.getMethod().getAnnotation(RedisCacheAspect.class);
        // 参数
        Object[] args = joinPoint.getArgs();
        String redisKey = null;
        if (args != null && args.length == 1) {
            // 从缓存中取数据
            redisKey = RedisUtil.getRedisKey(args[0], aspect.dir());
            Object redisObj = RedisUtil.getValue(redisTemplate, redisKey);
            if (redisObj != null) {
                if (aspect.needPage()) {
                    long total = Long.parseLong(RedisUtil.getValue(redisTemplate, redisKey + ">count").toString());
                    return new PageResDTO<>(total, (List<Object>) redisObj);
                } else {
                    return redisObj;
                }
            }
        }

        // 未取到数据，则执行原方法
        if (aspect.needPage()) {
            PageResDTO<Object> pageResVO = (PageResDTO<Object>) joinPoint.proceed();
            if (redisKey != null) {
                RedisUtil.setValue(redisTemplate, redisKey, pageResVO.getRows(), aspect.time(), aspect.timeUnit());
                RedisUtil.setValue(redisTemplate, redisKey + ">count", pageResVO.getTotal(), aspect.time(),
                        aspect.timeUnit());
            }
            return pageResVO;
        } else {
            Object object = joinPoint.proceed();
            RedisUtil.setValue(redisTemplate, redisKey, object, aspect.time(), aspect.timeUnit());
            return object;
        }
    }
}
